
#region Using Statements
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using XnaStage;

#endregion

namespace OrigPacman
{
	/// <summary>
	/// This is the main type for your game
	/// </summary>
	public class Game1 : Microsoft.Xna.Framework.Game
	{
		GraphicsDeviceManager graphics;
		ContentManager content;
		                                                             
		Pacman pacman;

		KeyPress.KeyPressGame keys;

		AudioEngine audioEngine;
		WaveBank waveBank;
		SoundBank soundBank;

		TextSprite scoreText;
		TextSprite scoreLabel;
		TextSprite livesLabel;
		TextSprite livesText;

		bool isPaused = false;
	
		#region ghost data
		Ghost redGhost;
		Ghost blueGhost;
		Ghost purpleGhost;
		Ghost greenGhost;
		List<Ghost> listOfGhosts;
		List<Map.Waypoints> listWayPoints;
		Random rand;
		// Specify file, instructions, and privelegdes
		//FileStream file = new FileStream("logging.txt", FileMode.Create, FileAccess.Write);
		//StreamWriter sw;
		//Map.Waypoints tmpWay; //tmp variable for waypoints
		#endregion

		Map.Map map;
		SpriteBatch sprite;

		#region game methods
		public Game1()
		{
			graphics = new GraphicsDeviceManager(this);
			content = new ContentManager(Services);

			pacman = new Pacman();

			keys = new KeyPress.KeyPressGame();

			map = new Map.Map(graphics.GraphicsDevice);
			pacman.CurrentWaypoints=map.getWaypoints();

			redGhost = new Ghost(Ghost.Colors.RED, new Vector2(100, 200));
			blueGhost = new Ghost(Ghost.Colors.BLUE, new Vector2(200, 200));
			purpleGhost = new Ghost(Ghost.Colors.PURPLE, new Vector2(300, 300));
			greenGhost = new Ghost(Ghost.Colors.GREEN, new Vector2(400, 400));


			listOfGhosts = new List<Ghost>();
			listOfGhosts.Add(redGhost);
			listOfGhosts.Add(blueGhost);
			listOfGhosts.Add(purpleGhost);
			listOfGhosts.Add(greenGhost);

			foreach (Ghost a in listOfGhosts)
				a.Waypoints = map.getWaypoints();
			listWayPoints = new List<Map.Waypoints>();
			rand = new Random();
			// Create a new stream to write to the file
			//sw = new StreamWriter(file);
			//sw.Write("Hello Testing");
		}


		/// <summary>
		/// Allows the game to perform any initialization it needs to before starting to run.
		/// This is where it can query for any required services and load any non-graphic
		/// related content.  Calling base.Initialize will enumerate through any components
		/// and initialize them as well.
		/// </summary>
		protected override void Initialize()
		{
			// TODO: Add your initialization logic here
			audioEngine = new AudioEngine("sound.xgs");
			waveBank = new WaveBank(audioEngine, "Wave Bank.xwb");
			soundBank = new SoundBank(audioEngine, "Sound Bank.xsb");
			TextSprite.Init(graphics.GraphicsDevice, content);
			TextStyle ts = new TextStyle("Joint", TextStyle.TextJustify.Center, TextStyle.VerticalAlign.Middle);
			scoreLabel = new TextSprite(ts, "Score:", new Vector2(685, 75), .8f);
			scoreLabel.DrawingColor = Color.White;
			scoreText = new TextSprite(ts, "0", new Vector2(685, 125), .8f);
			scoreText.DrawingColor = Color.LightGreen;
			livesLabel = new TextSprite(ts, "Lives:", new Vector2(685, 325), .8f);
			livesLabel.DrawingColor = Color.White;
			livesText = new TextSprite(ts, pacman.Lives.ToString(), new Vector2(685, 375), .8f);
			livesText.DrawingColor = Color.LightGreen;

			base.Initialize();
		}


		/// <summary>
		/// Load your graphics content.  If loadAllContent is true, you should
		/// load content from both ResourceManagementMode pools.  Otherwise, just
		/// load ResourceManagementMode.Manual content.
		/// </summary>
		/// <param name="loadAllContent">Which type of content to load.</param>
		protected override void LoadGraphicsContent(bool loadAllContent)
		{
			if (loadAllContent)
			{
				sprite = new SpriteBatch(graphics.GraphicsDevice);
				// TODO: Load any ResourceManagementMode.Automatic content
				pacman.PacmanUp = content.Load<Texture2D>("PacmanUp");
				pacman.PacmanDown = content.Load<Texture2D>("PacmanDown");
				pacman.PacmanRight = content.Load<Texture2D>("PacmanRight");
				pacman.PacmanLeft = content.Load<Texture2D>("PacmanLeft");
				pacman.DeathFrames = content.Load<Texture2D>("deathAnim");
				pacman.CurrentTexture = pacman.PacmanRight;
				map.LoadContent(content);
				redGhost.Texture = content.Load<Texture2D>("red");
				blueGhost.Texture = content.Load<Texture2D>("blue");
				purpleGhost.Texture = content.Load<Texture2D>("blue");
				greenGhost.Texture = content.Load<Texture2D>("green");
			}

			// TODO: Load any ResourceManagementMode.Manual content
		}


		/// <summary>
		/// Unload your graphics content.  If unloadAllContent is true, you should
		/// unload content from both ResourceManagementMode pools.  Otherwise, just
		/// unload ResourceManagementMode.Manual content.  Manual content will get
		/// Disposed by the GraphicsDevice during a Reset.
		/// </summary>
		/// <param name="unloadAllContent">Which type of content to unload.</param>
		protected override void UnloadGraphicsContent(bool unloadAllContent)
		{
			if (unloadAllContent == true)
			{
				content.Unload();
			}
		}


		/// <summary>
		/// Allows the game to run logic such as updating the world,
		/// checking for collisions, gathering input and playing audio.
		/// </summary>
		/// <param name="gameTime">Provides a snapshot of timing values.</param>
		protected override void Update(GameTime gameTime)
		{
			// Allows the default game to exit on Xbox 360 and Windows
			if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
				this.Exit();

			audioEngine.Update();

			// TODO: Add your update logic here
			// The time since Update was called last
			float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
			KeyPress.KeyPressGame.UpdateInput(elapsed);
			if (wasEscapePressed() == false)
			{
				if (!isPaused)
				{
					// TODO: Add your game logic here
					foreach (Ghost a in listOfGhosts)
						a.UpdateGhost(elapsed, pacman.Position);
					pacman.CurrentGhostPositions = listOfGhosts;
					pacman.UpdatePacman(elapsed);
					if (pacman.Death)
					{
						soundBank.PlayCue("death");
						livesText.Text = pacman.Lives.ToString();
						if (pacman.Lives == 0)
						{
							isPaused = true;
							//this.Exit();
						}

					}
					map.Update(elapsed, pacman.Position);
					if (map.AteSmallPellet)
					{
						soundBank.PlayCue("munchSmall");
						pacman.Score++;
						scoreText.Text = pacman.Score.ToString();
					}
					else if (map.AteBigPellet)
					{
						soundBank.PlayCue("munchBig");
						pacman.Score++;
						scoreText.Text = pacman.Score.ToString();
					}
					if (map.IsEmpty)
						isPaused=true;
				}
			}

			base.Update(gameTime);
		}


		/// <summary>
		/// This is called when the game should draw itself.
		/// </summary>
		/// <param name="gameTime">Provides a snapshot of timing values.</param>
		protected override void Draw(GameTime gameTime)
		{
			graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

			// TODO: Add your drawing code here
			
			sprite.Begin(SpriteBlendMode.AlphaBlend);
			map.Render(ref sprite);
			pacman.RenderPacman(ref sprite);
			foreach (Ghost a in listOfGhosts)
				a.RenderGhost(ref sprite);
			scoreLabel.Draw(gameTime, sprite);
			scoreText.Draw(gameTime, sprite);
			livesLabel.Draw(gameTime, sprite);
			livesText.Draw(gameTime, sprite);
			sprite.End();

			base.Draw(gameTime);
		}

		private bool wasEscapePressed()
		{
			if (KeyPress.KeyPressGame.KeyPressedThisFrame(Keys.Escape))
			{
				this.Exit();
				return true;
			}
			return false;
        }
        #endregion
    }
}